library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(readr)
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.3     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.2     ── Conflicts ────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(ggplot2)
library(highcharter)
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Highcharts (www.highcharts.com) is a Highsoft software product which is
not free for commercial and Governmental use
library(magrittr)

Attaching package: ‘magrittr’

The following object is masked from ‘package:purrr’:

    set_names

The following object is masked from ‘package:tidyr’:

    extract

EDA

Data loading

data <- read_csv("https://raw.githubusercontent.com/Alexburk93/Data_Wrangling_EDA/main/data/suicide_analysis.csv")
New names:Rows: 894 Columns: 22── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (13): Country name, Code, Indicator Name, Indicator Code, VAR, Variable, MEA, Measure, ISIC4...17, ISIC4...18, U...
dbl  (9): Year, Age-standardized suicide rate - Sex: both sexes, Life Ladder, Social support, Healthy life expectanc...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
                data %>% sample_n(19)

Renaming variables and drop unwanted columns

# renaming the columns 
data <- data %>%
  rename(`Country_name` = `Country name`,
         `Suicide_Rate` = `Age-standardized suicide rate - Sex: both sexes`,
         `Life_ladder` = `Life Ladder`,
         `Social_support` = `Social support`,
         `Life_expectancy` = `Healthy life expectancy at birth`,
         `Freedom_choices` = `Freedom to make life choices`,
         `Corruption` = `Perceptions of corruption`,
         `Indicator_name` = `Indicator Name`,
         `Indicator_code` = `Indicator Code`)

# drop columns 
# remove the original 'Time' column
data <- select(data, -Variable, -ISIC4...17, -ISIC4...18, -VAR, -MEA, -`Unit Code`)  
data

Data exploration

head(data)
# change names
names(data) <- make.names(names(data))
# dimensions of the dataframe
nrow(data)
[1] 894
ncol(data)
[1] 16
dim(data)
[1] 894  16
# check the structure of the object
str(data)
tibble [894 × 16] (S3: tbl_df/tbl/data.frame)
 $ Country_name   : chr [1:894] "Australia" "Australia" "Australia" "Australia" ...
 $ Code           : chr [1:894] "AUS" "AUS" "AUS" "AUS" ...
 $ Year           : num [1:894] 2011 2011 2011 2011 2011 ...
 $ Suicide_Rate   : num [1:894] 10.1 10.1 10.1 10.1 11 ...
 $ Life_ladder    : num [1:894] 7.41 7.41 7.41 7.41 7.19 ...
 $ Social_support : num [1:894] 0.967 0.967 0.967 0.967 0.954 ...
 $ Life_expectancy: num [1:894] 72.3 72.3 72.3 72.3 72.1 ...
 $ Freedom_choices: num [1:894] 0.945 0.945 0.945 0.945 0.935 ...
 $ Corruption     : num [1:894] 0.382 0.382 0.382 0.382 0.269 ...
 $ Indicator_name : chr [1:894] "GDP (current US$)" "GDP (current US$)" "GDP (current US$)" "GDP (current US$)" ...
 $ Indicator_code : chr [1:894] "NY.GDP.MKTP.CD" "NY.GDP.MKTP.CD" "NY.GDP.MKTP.CD" "NY.GDP.MKTP.CD" ...
 $ GDP            : num [1:894] 1.40e+12 1.40e+12 1.40e+12 1.40e+12 1.68e+11 ...
 $ Measure        : chr [1:894] "Index 2007=100" "Index 2007=100" "Index 2007=100" "Index 2007=100" ...
 $ Unit           : chr [1:894] "Index" "Index" "Index" "Index" ...
 $ Value          : num [1:894] 132 138 143 145 122 ...
 $ Quarter        : chr [1:894] "Q1" "Q2" "Q3" "Q4" ...
# look at columns 6, 7 and 10
head(data[ , c(2, 4:6, 12, 15)])
# look at columns 6, 7 and 10
tail(data[ , c(1, 3, 9)])
table(data$Year)

2011 2012 2013 2014 2015 2016 2017 2018 2019 
 100  100  100  100  100  100  100   97   97 
data %>% 
  select(Country_name) %>% 
  unique() %>% 
  nrow()
[1] 19
unique(data$Country_name)
 [1] "Australia"      "New Zealand"    "United States"  "Spain"          "Netherlands"    "France"        
 [7] "Finland"        "Belgium"        "Japan"          "South Africa"   "Iceland"        "Norway"        
[13] "Sweden"         "Italy"          "Brazil"         "United Kingdom" "Germany"        "Canada"        
[19] "Denmark"       
unique(data$Year)
[1] 2011 2012 2013 2014 2015 2016 2017 2018 2019

Interactive maps

# Set highcharter options for tooltip decimals
options(highcharter.tooltip.valueDecimals = 2)

# Create highcharter map visualization
hc <- highchart() %>%
  hc_add_series_map(
    worldgeojson, data, value = "GDP", 
    joinBy = c('name', 'Country_name'),
    name = "GDP (current US$)"
  )  %>% 
  hc_colorAxis(stops = color_stops()) %>% 
  hc_title(text = "World Map") %>% 
  hc_subtitle(text = "GDP in current US$")

hc
# Set highcharter options for tooltip decimals
options(highcharter.tooltip.valueDecimals = 2)

# Create map visualizations for each variable
hc_life_expectancy <- highchart() %>%
  hc_add_series_map(
    worldgeojson, data, 
    value = "Life_expectancy", 
    joinBy = c('name', 'Country_name'),
    name = "Life Expectancy"
  ) %>%
  hc_colorAxis(stops = color_stops()) %>%
  hc_title(text = "World Map") %>%
  hc_subtitle(text = "Life Expectancy")

hc_suicide_rates <- highchart() %>%
  hc_add_series_map(
    worldgeojson, data, 
    value = "Suicide_Rate", 
    joinBy = c('name', 'Country_name'),
    name = "Suicide Rates"
  ) %>%
  hc_colorAxis(stops = color_stops()) %>%
  hc_title(text = "World Map") %>%
  hc_subtitle(text = "Suicide Rate")

hc_corruption <- highchart() %>%
  hc_add_series_map(
    worldgeojson, data, 
    value = "Corruption", 
    joinBy = c('name', 'Country_name'),
    name = "Corruption"
  ) %>%
  hc_colorAxis(stops = color_stops()) %>%
  hc_title(text = "World Map") %>%
  hc_subtitle(text = "Corruption")

# Display the map visualizations
list(hc_life_expectancy, hc_suicide_rates, hc_corruption)
[[1]]

[[2]]

[[3]]
NA

AVG GDP over years

Calculation

avg_gdp_per_year <- data %>% 
  group_by (`Year`) %>% 
  summarise(avg_gpd = mean(`GDP`))

avg_gdp_per_year

Plot

ggplot(avg_gdp_per_year, aes(x = Year, y = avg_gpd)) +
  geom_line(color = "blue") +  
  labs(title = "Average GDP Over Time worldwide",
       x = "Year",
       y = "GDP") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_gdp_per_year$Year), max(avg_gdp_per_year$Year), by = 1))

AVG Happiness over years

Calculation

avg_happiness_per_year <- data %>% 
  group_by (`Year`) %>% 
  summarise(avg_happinnes = mean(`Life_ladder`, na.rm = T))

avg_happiness_per_year

Plot

ggplot(avg_happiness_per_year, aes(x = Year, y = avg_happinnes)) +
  geom_line(color = "blue") +  
  labs(title = "Average Happiness Over Time worldwide",
       x = "Year",
       y = "Happiness") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_happiness_per_year$Year), max(avg_happiness_per_year$Year), by = 1))

AVG Suicide Rates over years

Calculation

avg_Suicide_Rate_per_year <- data %>% 
  group_by (`Year`) %>% 
  summarise(avg_Suicide_Rate = mean(`Suicide_Rate`, na.rm = T))

avg_Suicide_Rate_per_year

Plot

ggplot(avg_Suicide_Rate_per_year, aes(x = Year, y = avg_Suicide_Rate)) +
  geom_line(color = "blue") +  
  labs(title = "Average Suicide Rate Over Time worldwide",
       x = "Year",
       y = "Suicide Rate") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_Suicide_Rate_per_year$Year), max(avg_Suicide_Rate_per_year$Year), by = 1))

AVG Bankruptcies over years

Calculation

avg_Bankruptcies_per_year <- data %>% 
  group_by (`Year`) %>% 
  summarise(avg_Bankruptcies = mean(`Value`, na.rm = T))

avg_Bankruptcies_per_year

Plot

ggplot(avg_Bankruptcies_per_year, aes(x = Year, y = avg_Bankruptcies)) +
  geom_line(color = "blue") +  
  labs(title = "Average Bankruptcies Over Time worldwide",
       x = "Year",
       y = "Bankruptcies") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_Bankruptcies_per_year$Year), max(avg_Bankruptcies_per_year$Year), by = 1))

Plot Average GDP and Average Suicide Rate over years

# Finding the ratio for scaling the second axis
ratio <- max(avg_gdp_per_year$avg_gpd) / max(avg_Suicide_Rate_per_year$avg_Suicide_Rate)

# Creating the base plot
ggplot() +
  # Adding the bar plot for GDP
  geom_bar(data = avg_gdp_per_year, aes(x = Year, y = avg_gpd), stat = "identity", fill = "skyblue", width = 0.2) +
  # Adding the line plot for Average Happiness
  geom_line(data = avg_Suicide_Rate_per_year, aes(x = Year, y = avg_Suicide_Rate * ratio), color = "red", size = 1.5) +
  # Enhancing the plot
  labs(title = "Average GDP and Suicide Rate Over Time",
       x = "Year",
       y = "Average GDP") +
  scale_y_continuous(sec.axis = sec_axis(~ . / ratio, name = "Average Suicide Rate")) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(c(avg_gdp_per_year$Year, avg_Suicide_Rate_per_year$Year)), 
                                  max(c(avg_gdp_per_year$Year, avg_Suicide_Rate_per_year$Year)), by = 1))
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
Please use `linewidth` instead.

Plot Average Happinness and Average Suicide Rate over years

# Finding the ratio for scaling the second axis
ratio <- max(avg_happiness_per_year$avg_happinnes) / max(avg_Suicide_Rate_per_year$avg_Suicide_Rate)

# Creating the base plot
ggplot() +
  # Adding the bar plot for GDP
  geom_bar(data = avg_happiness_per_year, aes(x = Year, y = avg_happinnes), stat = "identity", fill = "skyblue", width = 0.2) +
  # Adding the line plot for Average Happiness
  geom_line(data = avg_Suicide_Rate_per_year, aes(x = Year, y = avg_Suicide_Rate * ratio), color = "red", size = 1.5) +
  # Enhancing the plot
  labs(title = "Average Happinness and Suicide Rate Over Time",
       x = "Year",
       y = "Average Happinness") +
  scale_y_continuous(sec.axis = sec_axis(~ . / ratio, name = "Average Suicide Rate")) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(c(avg_happiness_per_year$Year, avg_Suicide_Rate_per_year$Year)), 
                                  max(c(avg_happiness_per_year$Year, avg_Suicide_Rate_per_year$Year)), by = 1))

Plot Average Bankruptcies and Average Suicide Rate over years

# Finding the ratio for scaling the second axis
ratio <- max(avg_Bankruptcies_per_year$avg_Bankruptcies) / max(avg_Suicide_Rate_per_year$avg_Suicide_Rate)

# Creating the base plot
ggplot() +
  # Adding the bar plot for GDP
  geom_bar(data = avg_Bankruptcies_per_year, aes(x = Year, y = avg_Bankruptcies), stat = "identity", fill = "skyblue", width = 0.2) +
  # Adding the line plot for Average Happiness
  geom_line(data = avg_Suicide_Rate_per_year, aes(x = Year, y = avg_Suicide_Rate * ratio), color = "red", size = 1.5) +
  # Enhancing the plot
  labs(title = "Average Bankruptcies and Suicide Rate Over Time",
       x = "Year",
       y = "Average Bankruptcies") +
  scale_y_continuous(sec.axis = sec_axis(~ . / ratio, name = "Average Suicide Rate")) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(c(avg_Bankruptcies_per_year$Year, avg_Suicide_Rate_per_year$Year)), 
                                  max(c(avg_Bankruptcies_per_year$Year, avg_Suicide_Rate_per_year$Year)), by = 1))

Comparisions

Two Happiest and Two unhappiest countries vs average suicide rate

avg_Suicide_Rate_per_country = data %>%
  group_by(Country_name) %>%
  summarise(avg_suicide_rate = mean(Suicide_Rate, na.rm = TRUE)) %>%
  arrange(avg_suicide_rate) %>% 
  mutate(Row_Number = row_number())

avg_Suicide_Rate_per_country

avg_happiness_per_country <- data %>%
  group_by(Country_name) %>%
  summarise(avg_happiness = mean(Life_ladder, na.rm = TRUE)) %>%
  arrange(desc(avg_happiness))

least_happy =  tail(avg_happiness_per_country, 2)
most_happy = head(avg_happiness_per_country, 2)


avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% least_happy$Country_name)

# Interpretation: Japan and South Africa are two very unhappy countries. And they also have a high suicide rate

avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% most_happy$Country_name)

# Interpretation: Finland is a the second most happy country. But is still on place 16/19 when it comes to suicides

Two most wealthy countries and two most poor countries vs average suicide rate

avg_gdp_per_country <- data %>% 
  group_by (`Country_name`) %>% 
  summarise(avg_gpd = mean(`GDP`)) %>% 
  arrange(desc(avg_gpd))

least_gdp =  tail(avg_gdp_per_country, 2)
most_gdp = head(avg_gdp_per_country, 2)

avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% least_money$Country_name)
Error in `filter()`:
ℹ In argument: `Country_name %in% least_money$Country_name`.
Caused by error:
! object 'least_money' not found
Backtrace:
 1. avg_Suicide_Rate_per_country %>% ...
 9. Country_name %in% least_money$Country_name

Two most bankcuptcies and two least bankcuptcies countries vs average suicide rate


avg_Bankruptcies_per_year <- data %>% 
  group_by (`Country_name`) %>% 
  summarise(avg_bankruptcies = mean(`Value`, na.rm = T)) %>% 
  arrange(desc(avg_bankruptcies))

least_bank =  tail(avg_Bankruptcies_per_year, 2)
most_bank = head(avg_Bankruptcies_per_year, 2)

avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% least_bank$Country_name)

# Interpretation: Bankruptcies don't have an influence on suicide rates

avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% most_bank$Country_name)

# Interpretation: Bankruptcies don't have an influence on suicide rates

In depth analysis Germany

Data preperation for Germany

# Prepare data for only Germany
germany_data = data %>% 
  filter(Country_name == "Germany")

Plot GDP Germany

# Plot Germany GDP over Years
avg_gdp_year_germany = germany_data %>% 
  group_by(Year) %>% 
  summarise(avg_gdp = mean(GDP)) 


ggplot(avg_gdp_year_germany, aes(x = Year, y = avg_gdp)) +
  geom_line(color = "blue") +  
  labs(title = "Average GPD Over Time - Germany",
       x = "Year",
       y = "GDP") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_gdp_year_germany$Year), max(avg_gdp_year_germany$Year), by = 1))

Plot Suicide Rate Germany

avg_suicide_year_germany = germany_data %>% 
  group_by(Year) %>% 
  summarise(avg_suicide = mean(Suicide_Rate)) 


ggplot(avg_suicide_year_germany, aes(x = Year, y = avg_suicide)) +
  geom_line(color = "blue") +  
  labs(title = "Average Suicide Rate Over Time - Germany",
       x = "Year",
       y = "Suicide Rate") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_suicide_year_germany$Year), max(avg_suicide_year_germany$Year), by = 1))

Plot Bankruptcies Rate Germany

avg_bank_year_germany = germany_data %>% 
  group_by(Year) %>% 
  summarise(avg_bank = mean(Value)) 


ggplot(avg_bank_year_germany, aes(x = Year, y = avg_bank)) +
  geom_line(color = "blue") +  
  labs(title = "Average bankruptcies Over Time - Germany",
       x = "Year",
       y = "Bankruptcies") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_bank_year_germany$Year), max(avg_bank_year_germany$Year), by = 1))

Plot Happiness Rate Germany

avg_happiness_year_germany = germany_data %>% 
  group_by(Year) %>% 
  summarise(avg_happy = mean(Life_ladder)) 


ggplot(avg_happiness_year_germany, aes(x = Year, y = avg_happy)) +
  geom_line(color = "blue") +  
  labs(title = "Average Happiness Over Time - Germany",
       x = "Year",
       y = "Happiness") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_happiness_year_germany$Year), max(avg_happiness_year_germany$Year), by = 1))

In depth analysis South Africa

Data preperation for South Africa

# Prepare data for only Germany
SA_data = data %>% 
  filter(Country_name == "South Africa")

Plot GDP SA

# Plot Germany GDP over Years
avg_gdp_year_SA = SA_data %>% 
  group_by(Year) %>% 
  summarise(avg_gdp = mean(GDP)) 



ggplot(avg_gdp_year_SA, aes(x = Year, y = avg_gdp)) +
  geom_line(color = "blue") +  
  labs(title = "Average GPD Over Time - SA",
       x = "Year",
       y = "GDP") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_gdp_year_SA$Year), max(avg_gdp_year_SA$Year), by = 1))

Plot Suicide Rate SA

avg_suicide_year_SA = SA_data %>% 
  group_by(Year) %>% 
  summarise(avg_suicide = mean(Suicide_Rate)) 


ggplot(avg_suicide_year_SA, aes(x = Year, y = avg_suicide)) +
  geom_line(color = "blue") +  
  labs(title = "Average Suicide Rate Over Time - SA",
       x = "Year",
       y = "Suicide Rate") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_suicide_year_SA$Year), max(avg_suicide_year_SA$Year), by = 1))

Plot Happiness Rate SA

avg_happiness_year_SA = SA_data %>% 
  group_by(Year) %>% 
  summarise(avg_happy = mean(Life_ladder)) 


ggplot(avg_happiness_year_SA, aes(x = Year, y = avg_happy)) +
  geom_line(color = "blue") +  
  labs(title = "Average Happiness Over Time - SA",
       x = "Year",
       y = "Happiness") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_happiness_year_SA$Year), max(avg_happiness_year_SA$Year), by = 1))

Plot Bankruptcies Rate SA

avg_bank_year_SA = SA_data %>% 
  group_by(Year) %>% 
  summarise(avg_bank = mean(Value)) 


ggplot(avg_bank_year_SA, aes(x = Year, y = avg_bank)) +
  geom_line(color = "blue") +  
  labs(title = "Average bankruptcies Over Time - SA",
       x = "Year",
       y = "Bankruptcies") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_bank_year_SA$Year), max(avg_bank_year_SA$Year), by = 1))

LS0tCnRpdGxlOiAiUHJlc2VudGF0aW9uIC0gRG9uJ3QgY29tbWl0IFN1aWNpZGUiCmF1dGhvcjogIk1hcmNrZW5yb2xkIENhZGV0ICYgQWxleGFuZGVyIEJ1cmtoYXJ0IgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDogCiAgIGh0bWxfbm90ZWJvb2s6CiAgICAgICB0b2M6IHRydWUgCiAgICAgICB0b2NfZmxvYXQ6IHRydWUKICAgICAgIHRvY19kZXB0aDogMgogICAgICAgdGhlbWU6IHVuaXRlZAogICAgICAgaGlnaGxpZ2h0OiB0YW5nbwotLS0KCmBgYHtyfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGhpZ2hjaGFydGVyKQpsaWJyYXJ5KG1hZ3JpdHRyKQpgYGAKIyBFREEKIyMgRGF0YSBsb2FkaW5nCmBgYHtyfQpkYXRhIDwtIHJlYWRfY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQWxleGJ1cms5My9EYXRhX1dyYW5nbGluZ19FREEvbWFpbi9kYXRhL3N1aWNpZGVfYW5hbHlzaXMuY3N2IikKICAgICAgICAgICAgICAgIGRhdGEgJT4lIHNhbXBsZV9uKDE5KQpgYGAKIyMgUmVuYW1pbmcgdmFyaWFibGVzIGFuZCBkcm9wIHVud2FudGVkIGNvbHVtbnMKYGBge3J9CiMgcmVuYW1pbmcgdGhlIGNvbHVtbnMgCmRhdGEgPC0gZGF0YSAlPiUKICByZW5hbWUoYENvdW50cnlfbmFtZWAgPSBgQ291bnRyeSBuYW1lYCwKICAgICAgICAgYFN1aWNpZGVfUmF0ZWAgPSBgQWdlLXN0YW5kYXJkaXplZCBzdWljaWRlIHJhdGUgLSBTZXg6IGJvdGggc2V4ZXNgLAogICAgICAgICBgTGlmZV9sYWRkZXJgID0gYExpZmUgTGFkZGVyYCwKICAgICAgICAgYFNvY2lhbF9zdXBwb3J0YCA9IGBTb2NpYWwgc3VwcG9ydGAsCiAgICAgICAgIGBMaWZlX2V4cGVjdGFuY3lgID0gYEhlYWx0aHkgbGlmZSBleHBlY3RhbmN5IGF0IGJpcnRoYCwKICAgICAgICAgYEZyZWVkb21fY2hvaWNlc2AgPSBgRnJlZWRvbSB0byBtYWtlIGxpZmUgY2hvaWNlc2AsCiAgICAgICAgIGBDb3JydXB0aW9uYCA9IGBQZXJjZXB0aW9ucyBvZiBjb3JydXB0aW9uYCwKICAgICAgICAgYEluZGljYXRvcl9uYW1lYCA9IGBJbmRpY2F0b3IgTmFtZWAsCiAgICAgICAgIGBJbmRpY2F0b3JfY29kZWAgPSBgSW5kaWNhdG9yIENvZGVgKQoKIyBkcm9wIGNvbHVtbnMgCiMgcmVtb3ZlIHRoZSBvcmlnaW5hbCAnVGltZScgY29sdW1uCmRhdGEgPC0gc2VsZWN0KGRhdGEsIC1WYXJpYWJsZSwgLUlTSUM0Li4uMTcsIC1JU0lDNC4uLjE4LCAtVkFSLCAtTUVBLCAtYFVuaXQgQ29kZWApICAKZGF0YQpgYGAKIyMgRGF0YSBleHBsb3JhdGlvbgpgYGB7cn0KaGVhZChkYXRhKQpgYGAKCmBgYHtyfQojIGNoYW5nZSBuYW1lcwpuYW1lcyhkYXRhKSA8LSBtYWtlLm5hbWVzKG5hbWVzKGRhdGEpKQpgYGAKCmBgYHtyfQojIGRpbWVuc2lvbnMgb2YgdGhlIGRhdGFmcmFtZQpucm93KGRhdGEpCm5jb2woZGF0YSkKZGltKGRhdGEpCmBgYAoKYGBge3J9CiMgY2hlY2sgdGhlIHN0cnVjdHVyZSBvZiB0aGUgb2JqZWN0CnN0cihkYXRhKQpgYGAKYGBge3J9CiMgbG9vayBhdCBjb2x1bW5zIDYsIDcgYW5kIDEwCmhlYWQoZGF0YVsgLCBjKDIsIDQ6NiwgMTIsIDE1KV0pCmBgYAoKYGBge3J9CiMgbG9vayBhdCBjb2x1bW5zIDYsIDcgYW5kIDEwCnRhaWwoZGF0YVsgLCBjKDEsIDMsIDkpXSkKYGBgCgpgYGB7cn0KdGFibGUoZGF0YSRZZWFyKQpgYGAKCgpgYGB7cn0KZGF0YSAlPiUgCiAgc2VsZWN0KENvdW50cnlfbmFtZSkgJT4lIAogIHVuaXF1ZSgpICU+JSAKICBucm93KCkKYGBgCgpgYGB7cn0KdW5pcXVlKGRhdGEkQ291bnRyeV9uYW1lKQpgYGAKCmBgYHtyfQp1bmlxdWUoZGF0YSRZZWFyKQpgYGAKCiMjIEludGVyYWN0aXZlIG1hcHMKYGBge3J9CiMgU2V0IGhpZ2hjaGFydGVyIG9wdGlvbnMgZm9yIHRvb2x0aXAgZGVjaW1hbHMKb3B0aW9ucyhoaWdoY2hhcnRlci50b29sdGlwLnZhbHVlRGVjaW1hbHMgPSAyKQoKIyBDcmVhdGUgaGlnaGNoYXJ0ZXIgbWFwIHZpc3VhbGl6YXRpb24KaGMgPC0gaGlnaGNoYXJ0KCkgJT4lCiAgaGNfYWRkX3Nlcmllc19tYXAoCiAgICB3b3JsZGdlb2pzb24sIGRhdGEsIHZhbHVlID0gIkdEUCIsIAogICAgam9pbkJ5ID0gYygnbmFtZScsICdDb3VudHJ5X25hbWUnKSwKICAgIG5hbWUgPSAiR0RQIChjdXJyZW50IFVTJCkiCiAgKSAgJT4lIAogIGhjX2NvbG9yQXhpcyhzdG9wcyA9IGNvbG9yX3N0b3BzKCkpICU+JSAKICBoY190aXRsZSh0ZXh0ID0gIldvcmxkIE1hcCIpICU+JSAKICBoY19zdWJ0aXRsZSh0ZXh0ID0gIkdEUCBpbiBjdXJyZW50IFVTJCIpCgpoYwpgYGAKCmBgYHtyfQojIFNldCBoaWdoY2hhcnRlciBvcHRpb25zIGZvciB0b29sdGlwIGRlY2ltYWxzCm9wdGlvbnMoaGlnaGNoYXJ0ZXIudG9vbHRpcC52YWx1ZURlY2ltYWxzID0gMikKCiMgQ3JlYXRlIG1hcCB2aXN1YWxpemF0aW9ucyBmb3IgZWFjaCB2YXJpYWJsZQpoY19saWZlX2V4cGVjdGFuY3kgPC0gaGlnaGNoYXJ0KCkgJT4lCiAgaGNfYWRkX3Nlcmllc19tYXAoCiAgICB3b3JsZGdlb2pzb24sIGRhdGEsIAogICAgdmFsdWUgPSAiTGlmZV9leHBlY3RhbmN5IiwgCiAgICBqb2luQnkgPSBjKCduYW1lJywgJ0NvdW50cnlfbmFtZScpLAogICAgbmFtZSA9ICJMaWZlIEV4cGVjdGFuY3kiCiAgKSAlPiUKICBoY19jb2xvckF4aXMoc3RvcHMgPSBjb2xvcl9zdG9wcygpKSAlPiUKICBoY190aXRsZSh0ZXh0ID0gIldvcmxkIE1hcCIpICU+JQogIGhjX3N1YnRpdGxlKHRleHQgPSAiTGlmZSBFeHBlY3RhbmN5IikKCmhjX3N1aWNpZGVfcmF0ZXMgPC0gaGlnaGNoYXJ0KCkgJT4lCiAgaGNfYWRkX3Nlcmllc19tYXAoCiAgICB3b3JsZGdlb2pzb24sIGRhdGEsIAogICAgdmFsdWUgPSAiU3VpY2lkZV9SYXRlIiwgCiAgICBqb2luQnkgPSBjKCduYW1lJywgJ0NvdW50cnlfbmFtZScpLAogICAgbmFtZSA9ICJTdWljaWRlIFJhdGVzIgogICkgJT4lCiAgaGNfY29sb3JBeGlzKHN0b3BzID0gY29sb3Jfc3RvcHMoKSkgJT4lCiAgaGNfdGl0bGUodGV4dCA9ICJXb3JsZCBNYXAiKSAlPiUKICBoY19zdWJ0aXRsZSh0ZXh0ID0gIlN1aWNpZGUgUmF0ZSIpCgpoY19jb3JydXB0aW9uIDwtIGhpZ2hjaGFydCgpICU+JQogIGhjX2FkZF9zZXJpZXNfbWFwKAogICAgd29ybGRnZW9qc29uLCBkYXRhLCAKICAgIHZhbHVlID0gIkNvcnJ1cHRpb24iLCAKICAgIGpvaW5CeSA9IGMoJ25hbWUnLCAnQ291bnRyeV9uYW1lJyksCiAgICBuYW1lID0gIkNvcnJ1cHRpb24iCiAgKSAlPiUKICBoY19jb2xvckF4aXMoc3RvcHMgPSBjb2xvcl9zdG9wcygpKSAlPiUKICBoY190aXRsZSh0ZXh0ID0gIldvcmxkIE1hcCIpICU+JQogIGhjX3N1YnRpdGxlKHRleHQgPSAiQ29ycnVwdGlvbiIpCgojIERpc3BsYXkgdGhlIG1hcCB2aXN1YWxpemF0aW9ucwpsaXN0KGhjX2xpZmVfZXhwZWN0YW5jeSwgaGNfc3VpY2lkZV9yYXRlcywgaGNfY29ycnVwdGlvbikKCmBgYAoKIyBBVkcgR0RQIG92ZXIgeWVhcnMKIyMgQ2FsY3VsYXRpb24gCmBgYHtyfQphdmdfZ2RwX3Blcl95ZWFyIDwtIGRhdGEgJT4lIAogIGdyb3VwX2J5IChgWWVhcmApICU+JSAKICBzdW1tYXJpc2UoYXZnX2dwZCA9IG1lYW4oYEdEUGApKQoKYXZnX2dkcF9wZXJfeWVhcgpgYGAKIyMgUGxvdCAKYGBge3J9CmdncGxvdChhdmdfZ2RwX3Blcl95ZWFyLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfZ3BkKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIEdEUCBPdmVyIFRpbWUgd29ybGR3aWRlIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkdEUCIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihhdmdfZ2RwX3Blcl95ZWFyJFllYXIpLCBtYXgoYXZnX2dkcF9wZXJfeWVhciRZZWFyKSwgYnkgPSAxKSkKYGBgCiMgQVZHIEhhcHBpbmVzcyBvdmVyIHllYXJzCiMjIENhbGN1bGF0aW9uIApgYGB7cn0KYXZnX2hhcHBpbmVzc19wZXJfeWVhciA8LSBkYXRhICU+JSAKICBncm91cF9ieSAoYFllYXJgKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19oYXBwaW5uZXMgPSBtZWFuKGBMaWZlX2xhZGRlcmAsIG5hLnJtID0gVCkpCgphdmdfaGFwcGluZXNzX3Blcl95ZWFyCmBgYAojIyBQbG90IAoKYGBge3J9CmdncGxvdChhdmdfaGFwcGluZXNzX3Blcl95ZWFyLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfaGFwcGlubmVzKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIEhhcHBpbmVzcyBPdmVyIFRpbWUgd29ybGR3aWRlIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkhhcHBpbmVzcyIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihhdmdfaGFwcGluZXNzX3Blcl95ZWFyJFllYXIpLCBtYXgoYXZnX2hhcHBpbmVzc19wZXJfeWVhciRZZWFyKSwgYnkgPSAxKSkKYGBgCgojIEFWRyBTdWljaWRlIFJhdGVzIG92ZXIgeWVhcnMKIyMgQ2FsY3VsYXRpb24gCmBgYHtyfQphdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyIDwtIGRhdGEgJT4lIAogIGdyb3VwX2J5IChgWWVhcmApICU+JSAKICBzdW1tYXJpc2UoYXZnX1N1aWNpZGVfUmF0ZSA9IG1lYW4oYFN1aWNpZGVfUmF0ZWAsIG5hLnJtID0gVCkpCgphdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyCmBgYAojIyBQbG90IAoKYGBge3J9CmdncGxvdChhdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfU3VpY2lkZV9SYXRlKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIFN1aWNpZGUgUmF0ZSBPdmVyIFRpbWUgd29ybGR3aWRlIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIlN1aWNpZGUgUmF0ZSIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihhdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyJFllYXIpLCBtYXgoYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciRZZWFyKSwgYnkgPSAxKSkKYGBgCiMgQVZHIEJhbmtydXB0Y2llcyBvdmVyIHllYXJzCiMjIENhbGN1bGF0aW9uIApgYGB7cn0KYXZnX0JhbmtydXB0Y2llc19wZXJfeWVhciA8LSBkYXRhICU+JSAKICBncm91cF9ieSAoYFllYXJgKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19CYW5rcnVwdGNpZXMgPSBtZWFuKGBWYWx1ZWAsIG5hLnJtID0gVCkpCgphdmdfQmFua3J1cHRjaWVzX3Blcl95ZWFyCmBgYAojIyBQbG90IAoKYGBge3J9CmdncGxvdChhdmdfQmFua3J1cHRjaWVzX3Blcl95ZWFyLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfQmFua3J1cHRjaWVzKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIEJhbmtydXB0Y2llcyBPdmVyIFRpbWUgd29ybGR3aWRlIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkJhbmtydXB0Y2llcyIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihhdmdfQmFua3J1cHRjaWVzX3Blcl95ZWFyJFllYXIpLCBtYXgoYXZnX0JhbmtydXB0Y2llc19wZXJfeWVhciRZZWFyKSwgYnkgPSAxKSkKYGBgCgojIFBsb3QgQXZlcmFnZSBHRFAgYW5kIEF2ZXJhZ2UgU3VpY2lkZSBSYXRlIG92ZXIgeWVhcnMKYGBge3J9CiMgRmluZGluZyB0aGUgcmF0aW8gZm9yIHNjYWxpbmcgdGhlIHNlY29uZCBheGlzCnJhdGlvIDwtIG1heChhdmdfZ2RwX3Blcl95ZWFyJGF2Z19ncGQpIC8gbWF4KGF2Z19TdWljaWRlX1JhdGVfcGVyX3llYXIkYXZnX1N1aWNpZGVfUmF0ZSkKCiMgQ3JlYXRpbmcgdGhlIGJhc2UgcGxvdApnZ3Bsb3QoKSArCiAgIyBBZGRpbmcgdGhlIGJhciBwbG90IGZvciBHRFAKICBnZW9tX2JhcihkYXRhID0gYXZnX2dkcF9wZXJfeWVhciwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX2dwZCksIHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInNreWJsdWUiLCB3aWR0aCA9IDAuMikgKwogICMgQWRkaW5nIHRoZSBsaW5lIHBsb3QgZm9yIEF2ZXJhZ2UgSGFwcGluZXNzCiAgZ2VvbV9saW5lKGRhdGEgPSBhdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfU3VpY2lkZV9SYXRlICogcmF0aW8pLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMS41KSArCiAgIyBFbmhhbmNpbmcgdGhlIHBsb3QKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgR0RQIGFuZCBTdWljaWRlIFJhdGUgT3ZlciBUaW1lIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkF2ZXJhZ2UgR0RQIikgKwogIHNjYWxlX3lfY29udGludW91cyhzZWMuYXhpcyA9IHNlY19heGlzKH4gLiAvIHJhdGlvLCBuYW1lID0gIkF2ZXJhZ2UgU3VpY2lkZSBSYXRlIikpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihjKGF2Z19nZHBfcGVyX3llYXIkWWVhciwgYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciRZZWFyKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KGMoYXZnX2dkcF9wZXJfeWVhciRZZWFyLCBhdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyJFllYXIpKSwgYnkgPSAxKSkKCmBgYAoKIyBQbG90IEF2ZXJhZ2UgSGFwcGlubmVzcyBhbmQgQXZlcmFnZSBTdWljaWRlIFJhdGUgb3ZlciB5ZWFycwpgYGB7cn0KIyBGaW5kaW5nIHRoZSByYXRpbyBmb3Igc2NhbGluZyB0aGUgc2Vjb25kIGF4aXMKcmF0aW8gPC0gbWF4KGF2Z19oYXBwaW5lc3NfcGVyX3llYXIkYXZnX2hhcHBpbm5lcykgLyBtYXgoYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciRhdmdfU3VpY2lkZV9SYXRlKQoKIyBDcmVhdGluZyB0aGUgYmFzZSBwbG90CmdncGxvdCgpICsKICAjIEFkZGluZyB0aGUgYmFyIHBsb3QgZm9yIEdEUAogIGdlb21fYmFyKGRhdGEgPSBhdmdfaGFwcGluZXNzX3Blcl95ZWFyLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfaGFwcGlubmVzKSwgc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAic2t5Ymx1ZSIsIHdpZHRoID0gMC4yKSArCiAgIyBBZGRpbmcgdGhlIGxpbmUgcGxvdCBmb3IgQXZlcmFnZSBIYXBwaW5lc3MKICBnZW9tX2xpbmUoZGF0YSA9IGF2Z19TdWljaWRlX1JhdGVfcGVyX3llYXIsIGFlcyh4ID0gWWVhciwgeSA9IGF2Z19TdWljaWRlX1JhdGUgKiByYXRpbyksIGNvbG9yID0gInJlZCIsIHNpemUgPSAxLjUpICsKICAjIEVuaGFuY2luZyB0aGUgcGxvdAogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBIYXBwaW5uZXNzIGFuZCBTdWljaWRlIFJhdGUgT3ZlciBUaW1lIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkF2ZXJhZ2UgSGFwcGlubmVzcyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoc2VjLmF4aXMgPSBzZWNfYXhpcyh+IC4gLyByYXRpbywgbmFtZSA9ICJBdmVyYWdlIFN1aWNpZGUgUmF0ZSIpKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYyhhdmdfaGFwcGluZXNzX3Blcl95ZWFyJFllYXIsIGF2Z19TdWljaWRlX1JhdGVfcGVyX3llYXIkWWVhcikpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChjKGF2Z19oYXBwaW5lc3NfcGVyX3llYXIkWWVhciwgYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciRZZWFyKSksIGJ5ID0gMSkpCgpgYGAKCiMgUGxvdCBBdmVyYWdlIEJhbmtydXB0Y2llcyBhbmQgQXZlcmFnZSBTdWljaWRlIFJhdGUgb3ZlciB5ZWFycwpgYGB7cn0KIyBGaW5kaW5nIHRoZSByYXRpbyBmb3Igc2NhbGluZyB0aGUgc2Vjb25kIGF4aXMKcmF0aW8gPC0gbWF4KGF2Z19CYW5rcnVwdGNpZXNfcGVyX3llYXIkYXZnX0JhbmtydXB0Y2llcykgLyBtYXgoYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciRhdmdfU3VpY2lkZV9SYXRlKQoKIyBDcmVhdGluZyB0aGUgYmFzZSBwbG90CmdncGxvdCgpICsKICAjIEFkZGluZyB0aGUgYmFyIHBsb3QgZm9yIEdEUAogIGdlb21fYmFyKGRhdGEgPSBhdmdfQmFua3J1cHRjaWVzX3Blcl95ZWFyLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfQmFua3J1cHRjaWVzKSwgc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAic2t5Ymx1ZSIsIHdpZHRoID0gMC4yKSArCiAgIyBBZGRpbmcgdGhlIGxpbmUgcGxvdCBmb3IgQXZlcmFnZSBIYXBwaW5lc3MKICBnZW9tX2xpbmUoZGF0YSA9IGF2Z19TdWljaWRlX1JhdGVfcGVyX3llYXIsIGFlcyh4ID0gWWVhciwgeSA9IGF2Z19TdWljaWRlX1JhdGUgKiByYXRpbyksIGNvbG9yID0gInJlZCIsIHNpemUgPSAxLjUpICsKICAjIEVuaGFuY2luZyB0aGUgcGxvdAogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBCYW5rcnVwdGNpZXMgYW5kIFN1aWNpZGUgUmF0ZSBPdmVyIFRpbWUiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiQXZlcmFnZSBCYW5rcnVwdGNpZXMiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHNlYy5heGlzID0gc2VjX2F4aXMofiAuIC8gcmF0aW8sIG5hbWUgPSAiQXZlcmFnZSBTdWljaWRlIFJhdGUiKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEobWluKGMoYXZnX0JhbmtydXB0Y2llc19wZXJfeWVhciRZZWFyLCBhdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyJFllYXIpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgoYyhhdmdfQmFua3J1cHRjaWVzX3Blcl95ZWFyJFllYXIsIGF2Z19TdWljaWRlX1JhdGVfcGVyX3llYXIkWWVhcikpLCBieSA9IDEpKQoKYGBgCgojIENvbXBhcmlzaW9ucwoKIyMgVHdvIEhhcHBpZXN0IGFuZCBUd28gdW5oYXBwaWVzdCBjb3VudHJpZXMgdnMgYXZlcmFnZSBzdWljaWRlIHJhdGUKYGBge3J9CmF2Z19TdWljaWRlX1JhdGVfcGVyX2NvdW50cnkgPSBkYXRhICU+JQogIGdyb3VwX2J5KENvdW50cnlfbmFtZSkgJT4lCiAgc3VtbWFyaXNlKGF2Z19zdWljaWRlX3JhdGUgPSBtZWFuKFN1aWNpZGVfUmF0ZSwgbmEucm0gPSBUUlVFKSkgJT4lCiAgYXJyYW5nZShhdmdfc3VpY2lkZV9yYXRlKSAlPiUgCiAgbXV0YXRlKFJvd19OdW1iZXIgPSByb3dfbnVtYmVyKCkpCgphdmdfU3VpY2lkZV9SYXRlX3Blcl9jb3VudHJ5CgphdmdfaGFwcGluZXNzX3Blcl9jb3VudHJ5IDwtIGRhdGEgJT4lCiAgZ3JvdXBfYnkoQ291bnRyeV9uYW1lKSAlPiUKICBzdW1tYXJpc2UoYXZnX2hhcHBpbmVzcyA9IG1lYW4oTGlmZV9sYWRkZXIsIG5hLnJtID0gVFJVRSkpICU+JQogIGFycmFuZ2UoZGVzYyhhdmdfaGFwcGluZXNzKSkKCmxlYXN0X2hhcHB5ID0gIHRhaWwoYXZnX2hhcHBpbmVzc19wZXJfY291bnRyeSwgMikKbW9zdF9oYXBweSA9IGhlYWQoYXZnX2hhcHBpbmVzc19wZXJfY291bnRyeSwgMikKCgphdmdfU3VpY2lkZV9SYXRlX3Blcl9jb3VudHJ5ICU+JSAKICBmaWx0ZXIoQ291bnRyeV9uYW1lICVpbiUgbGVhc3RfaGFwcHkkQ291bnRyeV9uYW1lKQoKIyBJbnRlcnByZXRhdGlvbjogSmFwYW4gYW5kIFNvdXRoIEFmcmljYSBhcmUgdHdvIHZlcnkgdW5oYXBweSBjb3VudHJpZXMuIEFuZCB0aGV5IGFsc28gaGF2ZSBhIGhpZ2ggc3VpY2lkZSByYXRlCgphdmdfU3VpY2lkZV9SYXRlX3Blcl9jb3VudHJ5ICU+JSAKICBmaWx0ZXIoQ291bnRyeV9uYW1lICVpbiUgbW9zdF9oYXBweSRDb3VudHJ5X25hbWUpCgojIEludGVycHJldGF0aW9uOiBGaW5sYW5kIGlzIGEgdGhlIHNlY29uZCBtb3N0IGhhcHB5IGNvdW50cnkuIEJ1dCBpcyBzdGlsbCBvbiBwbGFjZSAxNi8xOSB3aGVuIGl0IGNvbWVzIHRvIHN1aWNpZGVzCgpgYGAKCiMjIFR3byBtb3N0IHdlYWx0aHkgY291bnRyaWVzIGFuZCB0d28gbW9zdCBwb29yIGNvdW50cmllcyB2cyBhdmVyYWdlIHN1aWNpZGUgcmF0ZQpgYGB7cn0KYXZnX2dkcF9wZXJfY291bnRyeSA8LSBkYXRhICU+JSAKICBncm91cF9ieSAoYENvdW50cnlfbmFtZWApICU+JSAKICBzdW1tYXJpc2UoYXZnX2dwZCA9IG1lYW4oYEdEUGApKSAlPiUgCiAgYXJyYW5nZShkZXNjKGF2Z19ncGQpKQoKbGVhc3RfZ2RwID0gIHRhaWwoYXZnX2dkcF9wZXJfY291bnRyeSwgMikKbW9zdF9nZHAgPSBoZWFkKGF2Z19nZHBfcGVyX2NvdW50cnksIDIpCgphdmdfU3VpY2lkZV9SYXRlX3Blcl9jb3VudHJ5ICU+JSAKICBmaWx0ZXIoQ291bnRyeV9uYW1lICVpbiUgbGVhc3RfZ2RwJENvdW50cnlfbmFtZSkKCiMgSW50ZXJwcmV0YXRpb246IE5ldyBaZWFsYW5kIGFuZCBJY2VsYW5kIGFyZSB0d28gdmVyeSBzbWFsbCBjb3VudHJpZXMuICAKCmF2Z19TdWljaWRlX1JhdGVfcGVyX2NvdW50cnkgJT4lIAogIGZpbHRlcihDb3VudHJ5X25hbWUgJWluJSBtb3N0X2dkcCRDb3VudHJ5X25hbWUpCgojIEludGVycHJldGF0aW9uOiBUaGUgdHdvIGJpZ2dlc3QgZWNvbm9taWVzIGFyZSBiYXNlZCBvbiB0aGUgbG93ZXIgZW5kIG9mIHN1aWNpZGUgcmF0ZXMKYGBgCgoKIyMgVHdvIG1vc3QgYmFua2N1cHRjaWVzIGFuZCB0d28gbGVhc3QgYmFua2N1cHRjaWVzIGNvdW50cmllcyB2cyBhdmVyYWdlIHN1aWNpZGUgcmF0ZQpgYGB7cn0KCmF2Z19CYW5rcnVwdGNpZXNfcGVyX3llYXIgPC0gZGF0YSAlPiUgCiAgZ3JvdXBfYnkgKGBDb3VudHJ5X25hbWVgKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19iYW5rcnVwdGNpZXMgPSBtZWFuKGBWYWx1ZWAsIG5hLnJtID0gVCkpICU+JSAKICBhcnJhbmdlKGRlc2MoYXZnX2JhbmtydXB0Y2llcykpCgpsZWFzdF9iYW5rID0gIHRhaWwoYXZnX0JhbmtydXB0Y2llc19wZXJfeWVhciwgMikKbW9zdF9iYW5rID0gaGVhZChhdmdfQmFua3J1cHRjaWVzX3Blcl95ZWFyLCAyKQoKYXZnX1N1aWNpZGVfUmF0ZV9wZXJfY291bnRyeSAlPiUgCiAgZmlsdGVyKENvdW50cnlfbmFtZSAlaW4lIGxlYXN0X2JhbmskQ291bnRyeV9uYW1lKQoKIyBJbnRlcnByZXRhdGlvbjogQmFua3J1cHRjaWVzIGRvbid0IGhhdmUgYW4gaW5mbHVlbmNlIG9uIHN1aWNpZGUgcmF0ZXMKCmF2Z19TdWljaWRlX1JhdGVfcGVyX2NvdW50cnkgJT4lIAogIGZpbHRlcihDb3VudHJ5X25hbWUgJWluJSBtb3N0X2JhbmskQ291bnRyeV9uYW1lKQoKIyBJbnRlcnByZXRhdGlvbjogQmFua3J1cHRjaWVzIGRvbid0IGhhdmUgYW4gaW5mbHVlbmNlIG9uIHN1aWNpZGUgcmF0ZXMKYGBgCiMgSW4gZGVwdGggYW5hbHlzaXMgR2VybWFueQojIyBEYXRhIHByZXBlcmF0aW9uIGZvciBHZXJtYW55CmBgYHtyfQojIFByZXBhcmUgZGF0YSBmb3Igb25seSBHZXJtYW55Cmdlcm1hbnlfZGF0YSA9IGRhdGEgJT4lIAogIGZpbHRlcihDb3VudHJ5X25hbWUgPT0gIkdlcm1hbnkiKQpgYGAKCiMjIFBsb3QgR0RQIEdlcm1hbnkKYGBge3J9CiMgUGxvdCBHZXJtYW55IEdEUCBvdmVyIFllYXJzCmF2Z19nZHBfeWVhcl9nZXJtYW55ID0gZ2VybWFueV9kYXRhICU+JSAKICBncm91cF9ieShZZWFyKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19nZHAgPSBtZWFuKEdEUCkpIAoKCmdncGxvdChhdmdfZ2RwX3llYXJfZ2VybWFueSwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX2dkcCkpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIpICsgIAogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBHUEQgT3ZlciBUaW1lIC0gR2VybWFueSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJHRFAiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX2dkcF95ZWFyX2dlcm1hbnkkWWVhciksIG1heChhdmdfZ2RwX3llYXJfZ2VybWFueSRZZWFyKSwgYnkgPSAxKSkKCmBgYAoKIyMgUGxvdCBTdWljaWRlIFJhdGUgR2VybWFueQpgYGB7cn0KYXZnX3N1aWNpZGVfeWVhcl9nZXJtYW55ID0gZ2VybWFueV9kYXRhICU+JSAKICBncm91cF9ieShZZWFyKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19zdWljaWRlID0gbWVhbihTdWljaWRlX1JhdGUpKSAKCgpnZ3Bsb3QoYXZnX3N1aWNpZGVfeWVhcl9nZXJtYW55LCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfc3VpY2lkZSkpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIpICsgIAogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBTdWljaWRlIFJhdGUgT3ZlciBUaW1lIC0gR2VybWFueSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJTdWljaWRlIFJhdGUiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX3N1aWNpZGVfeWVhcl9nZXJtYW55JFllYXIpLCBtYXgoYXZnX3N1aWNpZGVfeWVhcl9nZXJtYW55JFllYXIpLCBieSA9IDEpKQpgYGAKIyMgUGxvdCBCYW5rcnVwdGNpZXMgUmF0ZSBHZXJtYW55CmBgYHtyfQphdmdfYmFua195ZWFyX2dlcm1hbnkgPSBnZXJtYW55X2RhdGEgJT4lIAogIGdyb3VwX2J5KFllYXIpICU+JSAKICBzdW1tYXJpc2UoYXZnX2JhbmsgPSBtZWFuKFZhbHVlKSkgCgoKZ2dwbG90KGF2Z19iYW5rX3llYXJfZ2VybWFueSwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX2JhbmspKSArCiAgZ2VvbV9saW5lKGNvbG9yID0gImJsdWUiKSArICAKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgYmFua3J1cHRjaWVzIE92ZXIgVGltZSAtIEdlcm1hbnkiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiQmFua3J1cHRjaWVzIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEobWluKGF2Z19iYW5rX3llYXJfZ2VybWFueSRZZWFyKSwgbWF4KGF2Z19iYW5rX3llYXJfZ2VybWFueSRZZWFyKSwgYnkgPSAxKSkKYGBgCiMjIFBsb3QgSGFwcGluZXNzIFJhdGUgR2VybWFueQpgYGB7cn0KYXZnX2hhcHBpbmVzc195ZWFyX2dlcm1hbnkgPSBnZXJtYW55X2RhdGEgJT4lIAogIGdyb3VwX2J5KFllYXIpICU+JSAKICBzdW1tYXJpc2UoYXZnX2hhcHB5ID0gbWVhbihMaWZlX2xhZGRlcikpIAoKCmdncGxvdChhdmdfaGFwcGluZXNzX3llYXJfZ2VybWFueSwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX2hhcHB5KSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIEhhcHBpbmVzcyBPdmVyIFRpbWUgLSBHZXJtYW55IiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkhhcHBpbmVzcyIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihhdmdfaGFwcGluZXNzX3llYXJfZ2VybWFueSRZZWFyKSwgbWF4KGF2Z19oYXBwaW5lc3NfeWVhcl9nZXJtYW55JFllYXIpLCBieSA9IDEpKQpgYGAKIyBJbiBkZXB0aCBhbmFseXNpcyBTb3V0aCBBZnJpY2EKIyMgRGF0YSBwcmVwZXJhdGlvbiBmb3IgU291dGggQWZyaWNhCmBgYHtyfQojIFByZXBhcmUgZGF0YSBmb3Igb25seSBHZXJtYW55ClNBX2RhdGEgPSBkYXRhICU+JSAKICBmaWx0ZXIoQ291bnRyeV9uYW1lID09ICJTb3V0aCBBZnJpY2EiKQpgYGAKCiMjIFBsb3QgR0RQIFNBCmBgYHtyfQojIFBsb3QgR2VybWFueSBHRFAgb3ZlciBZZWFycwphdmdfZ2RwX3llYXJfU0EgPSBTQV9kYXRhICU+JSAKICBncm91cF9ieShZZWFyKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19nZHAgPSBtZWFuKEdEUCkpIAoKCgpnZ3Bsb3QoYXZnX2dkcF95ZWFyX1NBLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfZ2RwKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIEdQRCBPdmVyIFRpbWUgLSBTQSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJHRFAiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX2dkcF95ZWFyX1NBJFllYXIpLCBtYXgoYXZnX2dkcF95ZWFyX1NBJFllYXIpLCBieSA9IDEpKQoKYGBgCiMjIFBsb3QgU3VpY2lkZSBSYXRlIFNBCmBgYHtyfQphdmdfc3VpY2lkZV95ZWFyX1NBID0gU0FfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoWWVhcikgJT4lIAogIHN1bW1hcmlzZShhdmdfc3VpY2lkZSA9IG1lYW4oU3VpY2lkZV9SYXRlKSkgCgoKZ2dwbG90KGF2Z19zdWljaWRlX3llYXJfU0EsIGFlcyh4ID0gWWVhciwgeSA9IGF2Z19zdWljaWRlKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIFN1aWNpZGUgUmF0ZSBPdmVyIFRpbWUgLSBTQSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJTdWljaWRlIFJhdGUiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX3N1aWNpZGVfeWVhcl9TQSRZZWFyKSwgbWF4KGF2Z19zdWljaWRlX3llYXJfU0EkWWVhciksIGJ5ID0gMSkpCmBgYAoKIyMgUGxvdCBIYXBwaW5lc3MgUmF0ZSBTQQpgYGB7cn0KYXZnX2hhcHBpbmVzc195ZWFyX1NBID0gU0FfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoWWVhcikgJT4lIAogIHN1bW1hcmlzZShhdmdfaGFwcHkgPSBtZWFuKExpZmVfbGFkZGVyKSkgCgoKZ2dwbG90KGF2Z19oYXBwaW5lc3NfeWVhcl9TQSwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX2hhcHB5KSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIEhhcHBpbmVzcyBPdmVyIFRpbWUgLSBTQSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJIYXBwaW5lc3MiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX2hhcHBpbmVzc195ZWFyX1NBJFllYXIpLCBtYXgoYXZnX2hhcHBpbmVzc195ZWFyX1NBJFllYXIpLCBieSA9IDEpKQpgYGAKCiMjIFBsb3QgQmFua3J1cHRjaWVzIFJhdGUgU0EKYGBge3J9CmF2Z19iYW5rX3llYXJfU0EgPSBTQV9kYXRhICU+JSAKICBncm91cF9ieShZZWFyKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19iYW5rID0gbWVhbihWYWx1ZSkpIAoKCmdncGxvdChhdmdfYmFua195ZWFyX1NBLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfYmFuaykpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIpICsgIAogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBiYW5rcnVwdGNpZXMgT3ZlciBUaW1lIC0gU0EiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiQmFua3J1cHRjaWVzIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEobWluKGF2Z19iYW5rX3llYXJfU0EkWWVhciksIG1heChhdmdfYmFua195ZWFyX1NBJFllYXIpLCBieSA9IDEpKQpgYGA=